using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MT5Trade.Models
{
    /// <summary>
    /// 自适应对冲参数优化器 - 实现文档9.3.1节要求
    /// 整合所有优化组件，提供统一的参数调整接口
    /// 基于市场数据和账户状态动态优化交易参数
    /// </summary>
    public class AdaptiveHedgeOptimizer
    {
        #region 常量定义 - 基于文档9.2.2节敏感性指数

        // 参数敏感性权重（来自Sobol指数分析）
        public const double POSITION_SIZE_SENSITIVITY = 0.387;  // 仓位大小敏感性
        public const double STOP_LOSS_SENSITIVITY = 0.243;      // 止损位置敏感性
        public const double LEVERAGE_SENSITIVITY = 0.189;       // 杠杆比例敏感性
        public const double GAP_RATIO_SENSITIVITY = 0.156;      // 敞口比例敏感性
        public const double RETRY_COUNT_SENSITIVITY = 0.098;    // 重试次数敏感性

        // 优化频率设置（毫秒）
        public const int POSITION_UPDATE_FREQUENCY_MS = 0;      // 每笔交易
        public const int STOP_LOSS_UPDATE_FREQUENCY_MS = 900000; // 每15分钟
        public const int LEVERAGE_UPDATE_FREQUENCY_MS = 3600000; // 每小时
        public const int GAP_UPDATE_FREQUENCY_MS = 0;           // 每笔交易
        public const int RETRY_UPDATE_FREQUENCY_MS = 86400000;  // 每日

        // 调整步长
        public const double POSITION_ADJUSTMENT_STEP = 0.01;    // 0.01手
        public const double STOP_LOSS_ADJUSTMENT_STEP = 0.01;   // 1%
        public const double LEVERAGE_ADJUSTMENT_STEP = 10.0;    // 1:10
        public const double GAP_ADJUSTMENT_STEP = 0.01;         // 1%

        // 参数限制范围（基于文档9.5节风险控制矩阵）
        public const double MIN_POSITION_SIZE_NORMAL = 0.1;
        public const double MAX_POSITION_SIZE_NORMAL = 1.0;
        public const double MIN_LEVERAGE_NORMAL = 50.0;
        public const double MAX_LEVERAGE_NORMAL = 200.0;
        public const double MIN_GAP_RATIO = 0.0;
        public const double MAX_GAP_RATIO_NORMAL = 0.3;
        public const double MIN_STOP_LOSS_RATIO = 0.01;
        public const double MAX_STOP_LOSS_NORMAL = 0.05;

        #endregion

        #region 市场状态定义

        /// <summary>
        /// 市场状态枚举 - 基于文档9.5节
        /// </summary>
        public enum MarketState
        {
            Normal,    // 正常市况
            Warning,   // 警戒状态
            Danger     // 危险状态
        }

        #endregion

        #region 私有字段

        private readonly GarchModel _garchModel;
        private readonly KellyCalculator _kellyCalculator;
        private readonly RiskMetrics _riskMetrics;
        private readonly BankruptcyModel _bankruptcyModel;
        private readonly LeverageController _leverageController;
        private readonly NSGA2Optimizer _nsga2Optimizer;
        private readonly GapHedgingStrategy _gapHedgingStrategy;
        private readonly DynamicHedgeAdjuster _dynamicHedgeAdjuster;

        private readonly Dictionary<string, DateTime> _lastUpdateTimes;
        private readonly Dictionary<string, OptimizedParameters> _currentParameters;
        private readonly object _lockObj = new object();

        #endregion

        #region 优化参数结构

        /// <summary>
        /// 优化后的参数集合
        /// </summary>
        public class OptimizedParameters
        {
            public double PositionSize { get; set; }      // 优化后的仓位大小
            public double Leverage { get; set; }          // 优化后的杠杆比例
            public double StopLoss { get; set; }          // 优化后的止损位置
            public double GapRatio { get; set; }          // 优化后的敞口比例
            public int RetryCount { get; set; }           // 优化后的重试次数
            public double TrendStrength { get; set; }     // 趋势强度评估
            public double CurrentVolatility { get; set; }  // 当前波动率
            public double PredictedVolatility { get; set; } // 预测波动率
            public MarketState MarketCondition { get; set; } // 市场状态
            public DateTime OptimizationTime { get; set; }   // 优化时间
            public double ConfidenceScore { get; set; }      // 置信度评分(0-1)
        }

        #endregion

        #region 构造函数

        /// <summary>
        /// 初始化自适应对冲优化器
        /// </summary>
        public AdaptiveHedgeOptimizer(
            GarchModel garchModel,
            KellyCalculator kellyCalculator,
            RiskMetrics riskMetrics,
            BankruptcyModel bankruptcyModel,
            LeverageController leverageController,
            NSGA2Optimizer nsga2Optimizer,
            GapHedgingStrategy gapHedgingStrategy,
            DynamicHedgeAdjuster dynamicHedgeAdjuster)
        {
            _garchModel = garchModel ?? throw new ArgumentNullException(nameof(garchModel));
            _kellyCalculator = kellyCalculator ?? throw new ArgumentNullException(nameof(kellyCalculator));
            _riskMetrics = riskMetrics ?? throw new ArgumentNullException(nameof(riskMetrics));
            _bankruptcyModel = bankruptcyModel ?? throw new ArgumentNullException(nameof(bankruptcyModel));
            _leverageController = leverageController ?? throw new ArgumentNullException(nameof(leverageController));
            _nsga2Optimizer = nsga2Optimizer ?? throw new ArgumentNullException(nameof(nsga2Optimizer));
            _gapHedgingStrategy = gapHedgingStrategy ?? throw new ArgumentNullException(nameof(gapHedgingStrategy));
            _dynamicHedgeAdjuster = dynamicHedgeAdjuster ?? throw new ArgumentNullException(nameof(dynamicHedgeAdjuster));

            _lastUpdateTimes = new Dictionary<string, DateTime>();
            _currentParameters = new Dictionary<string, OptimizedParameters>();
        }

        #endregion

        #region 核心优化方法 - 实现文档9.3.1节算法

        /// <summary>
        /// 执行参数优化 - 基于市场数据和账户状态
        /// 实现文档9.3.1节的optimize_parameters方法
        /// </summary>
        /// <param name="marketData">市场数据</param>
        /// <param name="accountStatus">账户状态</param>
        /// <returns>优化后的参数集</returns>
        public async Task<OptimizedParameters> OptimizeParametersAsync(MarketData marketData, AccountStatus accountStatus)
        {
            if (marketData == null) throw new ArgumentNullException(nameof(marketData));
            if (accountStatus == null) throw new ArgumentNullException(nameof(accountStatus));

            lock (_lockObj)
            {
                var startTime = DateTime.Now;
                var symbol = marketData.Symbol;

                try
                {
                    // 步骤1：波动率预测（使用GARCH模型）
                    double currentVolatility = CalculateCurrentVolatility(marketData);
                    double predictedVolatility = PredictFutureVolatility(marketData);

                    // 步骤2：趋势强度评估
                    double trendStrength = CalculateTrendStrength(marketData);

                    // 步骤3：市场状态评估
                    MarketState marketState = DetermineMarketState(currentVolatility, accountStatus);

                    // 步骤4：优化各参数
                    // 首先计算仓位大小，用于后续止损计算
                    double optimizedPositionSize = OptimizePositionSize(trendStrength, predictedVolatility, accountStatus, marketState);

                    var optimizedParams = new OptimizedParameters
                    {
                        // 使用Kelly公式优化仓位
                        PositionSize = optimizedPositionSize,

                        // 基于破产概率模型优化杠杆
                        Leverage = OptimizeLeverage(predictedVolatility, accountStatus.MarginLevel, marketState),

                        // 使用VaR/CVaR计算止损
                        StopLoss = CalculateOptimalStopLoss(predictedVolatility, optimizedPositionSize, marketState),

                        // 优化敞口比例
                        GapRatio = OptimizeGapRatio(trendStrength, predictedVolatility, marketState),

                        // 基于网络延迟优化重试次数
                        RetryCount = OptimizeRetryCount(marketData.NetworkLatency, marketState),

                        // 记录附加信息
                        TrendStrength = trendStrength,
                        CurrentVolatility = currentVolatility,
                        PredictedVolatility = predictedVolatility,
                        MarketCondition = marketState,
                        OptimizationTime = startTime,
                        ConfidenceScore = CalculateConfidenceScore(marketData, accountStatus)
                    };

                    // 步骤5：风险检查
                    if (!PerformRiskCheck(optimizedParams, accountStatus))
                    {
                        // 如果风险检查失败，返回安全模式参数
                        return GetSafeModeParameters(marketState);
                    }

                    // 缓存优化结果
                    _currentParameters[symbol] = optimizedParams;
                    _lastUpdateTimes[$"{symbol}_optimization"] = startTime;

                    return optimizedParams;
                }
                catch (Exception ex)
                {
                    // 发生异常时返回安全模式参数
                    Console.WriteLine($"[AdaptiveHedgeOptimizer] 优化失败: {ex.Message}");
                    return GetSafeModeParameters(MarketState.Danger);
                }
            }
        }

        #endregion

        #region 参数优化方法

        /// <summary>
        /// 优化仓位大小 - 使用Kelly公式
        /// </summary>
        private double OptimizePositionSize(double trendStrength, double volatility, AccountStatus accountStatus, MarketState marketState)
        {
            // 基于Kelly公式计算最优仓位
            double winProbability = 0.5 + trendStrength * 0.3; // 基于趋势强度调整胜率
            double winLossRatio = 1.5; // 盈亏比

            double kellyFraction = _kellyCalculator.CalculateOptimalKellyFraction(winProbability, winLossRatio);

            // 应用安全系数
            double safeFactor = marketState switch
            {
                MarketState.Normal => 0.25,
                MarketState.Warning => 0.15,
                MarketState.Danger => 0.05,
                _ => 0.1
            };

            double optimalPosition = kellyFraction * safeFactor * accountStatus.Equity / accountStatus.MarginPerLot;

            // 根据市场状态限制仓位
            double maxPosition = marketState switch
            {
                MarketState.Normal => MAX_POSITION_SIZE_NORMAL,
                MarketState.Warning => 0.5,
                MarketState.Danger => 0.2,
                _ => 0.1
            };

            return Math.Max(MIN_POSITION_SIZE_NORMAL, Math.Min(maxPosition, Math.Round(optimalPosition, 2)));
        }

        /// <summary>
        /// 优化杠杆比例 - 基于破产概率模型
        /// </summary>
        private double OptimizeLeverage(double volatility, double marginLevel, MarketState marketState)
        {
            // 根据波动率级别确定杠杆
            double baseLeverage;
            if (volatility < BankruptcyModel.LOW_VOLATILITY_THRESHOLD)
            {
                baseLeverage = 200.0; // 低波动期：1:200
            }
            else if (volatility < BankruptcyModel.MEDIUM_VOLATILITY_THRESHOLD)
            {
                baseLeverage = 100.0; // 中波动期：1:100
            }
            else
            {
                baseLeverage = 50.0; // 高波动期：1:50
            }

            // 根据市场状态调整
            double leverageLimit = marketState switch
            {
                MarketState.Normal => MAX_LEVERAGE_NORMAL,
                MarketState.Warning => 100.0,
                MarketState.Danger => 50.0,
                _ => 50.0
            };

            double optimalLeverage = Math.Min(baseLeverage, leverageLimit);

            // 基于保证金水平进一步调整
            if (marginLevel < 200)
            {
                optimalLeverage *= 0.5; // 保证金紧张时降低杠杆
            }

            return Math.Max(MIN_LEVERAGE_NORMAL, optimalLeverage);
        }

        /// <summary>
        /// 计算最优止损位置 - 使用VaR模型
        /// </summary>
        private double CalculateOptimalStopLoss(double volatility, double positionSize, MarketState marketState)
        {
            // 基于VaR_95计算止损
            double baseStopLoss = 1.65 * volatility; // Z_SCORE_95 * volatility

            // 考虑仓位大小调整止损
            double positionAdjustment = Math.Sqrt(positionSize); // 仓位越大，止损越紧
            baseStopLoss *= (2.0 - positionAdjustment);

            // 根据市场状态限制止损
            double maxStopLoss = marketState switch
            {
                MarketState.Normal => MAX_STOP_LOSS_NORMAL,
                MarketState.Warning => 0.03,
                MarketState.Danger => 0.02,
                _ => 0.01
            };

            return Math.Max(MIN_STOP_LOSS_RATIO, Math.Min(maxStopLoss, baseStopLoss));
        }

        /// <summary>
        /// 优化敞口比例
        /// </summary>
        private double OptimizeGapRatio(double trendStrength, double volatility, MarketState marketState)
        {
            // 基础敞口比例
            double baseGapRatio = 0.1;

            // 趋势强度调整
            if (Math.Abs(trendStrength) > 0.7)
            {
                baseGapRatio = 0.15; // 强趋势时增加敞口
            }
            else if (Math.Abs(trendStrength) < 0.3)
            {
                baseGapRatio = 0.05; // 弱趋势时减少敞口
            }

            // 波动率调整
            if (volatility > 0.02)
            {
                baseGapRatio *= 0.5; // 高波动时减少敞口
            }

            // 市场状态限制
            double maxGapRatio = marketState switch
            {
                MarketState.Normal => MAX_GAP_RATIO_NORMAL,
                MarketState.Warning => 0.2,
                MarketState.Danger => 0.1,
                _ => 0.05
            };

            return Math.Max(MIN_GAP_RATIO, Math.Min(maxGapRatio, baseGapRatio));
        }

        /// <summary>
        /// 优化重试次数
        /// </summary>
        private int OptimizeRetryCount(double networkLatency, MarketState marketState)
        {
            // 基于网络延迟确定重试次数
            int baseRetryCount;
            if (networkLatency < 100)
            {
                baseRetryCount = 3; // 正常网络
            }
            else if (networkLatency < 500)
            {
                baseRetryCount = 5; // 中等延迟
            }
            else
            {
                baseRetryCount = 10; // 高延迟
            }

            // 根据市场状态调整
            if (marketState == MarketState.Danger)
            {
                baseRetryCount = Math.Min(baseRetryCount * 2, 15); // 危险时增加重试
            }

            return baseRetryCount;
        }

        #endregion

        #region 辅助方法

        /// <summary>
        /// 计算当前波动率
        /// </summary>
        private double CalculateCurrentVolatility(MarketData marketData)
        {
            if (marketData.Returns == null || marketData.Returns.Count < GarchModel.MIN_DATA_POINTS)
            {
                return 0.015; // 默认波动率1.5%
            }

            return _garchModel.GetCurrentVolatility(marketData.Returns.ToArray());
        }

        /// <summary>
        /// 预测未来波动率
        /// </summary>
        private double PredictFutureVolatility(MarketData marketData)
        {
            if (!_garchModel.IsEstimated)
            {
                // 如果GARCH模型未估计，先进行参数估计
                if (marketData.Returns != null && marketData.Returns.Count >= GarchModel.MIN_DATA_POINTS)
                {
                    _garchModel.EstimateParameters(marketData.Returns.ToArray());
                }
                else
                {
                    return 0.015; // 默认预测值
                }
            }

            // 预测下一期波动率
            var conditionalVariances = _garchModel.CalculateConditionalVariances(
                marketData.Returns.ToArray(),
                _garchModel.Omega,
                _garchModel.Alpha,
                _garchModel.Beta,
                _garchModel.Mu);

            double currentVariance = conditionalVariances[conditionalVariances.Length - 1];
            return _garchModel.PredictNextVolatility(currentVariance);
        }

        /// <summary>
        /// 计算趋势强度（-1到1）
        /// </summary>
        private double CalculateTrendStrength(MarketData marketData)
        {
            if (marketData.Prices == null || marketData.Prices.Count < 20)
            {
                return 0.0;
            }

            // 计算简单移动平均趋势
            var prices = marketData.Prices.TakeLast(50).ToList();
            double sma20 = prices.TakeLast(20).Average();
            double sma50 = prices.Average();
            double currentPrice = prices.Last();

            // 计算趋势强度
            double trendDirection = (sma20 - sma50) / sma50;
            double momentum = (currentPrice - sma20) / sma20;

            double trendStrength = (trendDirection + momentum) / 2.0;

            // 限制在[-1, 1]范围内
            return Math.Max(-1.0, Math.Min(1.0, trendStrength));
        }

        /// <summary>
        /// 确定市场状态
        /// </summary>
        private MarketState DetermineMarketState(double volatility, AccountStatus accountStatus)
        {
            // 基于波动率和账户状态判断市场状态
            bool highVolatility = volatility > 0.025;
            bool lowMargin = accountStatus.MarginLevel < 200;
            bool recentLosses = accountStatus.ConsecutiveLosses >= 3;

            if (highVolatility || lowMargin || recentLosses)
            {
                return MarketState.Danger;
            }
            else if (volatility > 0.015 || accountStatus.MarginLevel < 300 || accountStatus.ConsecutiveLosses >= 2)
            {
                return MarketState.Warning;
            }
            else
            {
                return MarketState.Normal;
            }
        }

        /// <summary>
        /// 执行风险检查
        /// </summary>
        private bool PerformRiskCheck(OptimizedParameters parameters, AccountStatus accountStatus)
        {
            // 检查仓位是否超过账户限制
            double maxAllowedPosition = accountStatus.FreeMargin / accountStatus.MarginPerLot;
            if (parameters.PositionSize > maxAllowedPosition)
            {
                return false;
            }

            // 检查破产概率
            double bankruptcyProbability = _bankruptcyModel.CalculateContinuousBankruptcyProbability(
                0.001, // 期望收益率
                parameters.PredictedVolatility,
                parameters.Leverage,
                accountStatus.Equity);

            if (bankruptcyProbability > BankruptcyModel.TARGET_BANKRUPTCY_PROBABILITY)
            {
                return false;
            }

            // 检查VaR限制
            double varLimit = accountStatus.Equity * 0.2; // 最大损失不超过20%权益
            double estimatedVar = _riskMetrics.CalculateParametricVaR(
                RiskMetrics.CONFIDENCE_LEVEL_95,
                parameters.PositionSize * accountStatus.MarginPerLot);

            if (estimatedVar > varLimit)
            {
                return false;
            }

            return true;
        }

        /// <summary>
        /// 计算置信度评分
        /// </summary>
        private double CalculateConfidenceScore(MarketData marketData, AccountStatus accountStatus)
        {
            double score = 0.5; // 基础分

            // 数据质量评分
            if (marketData.Returns != null && marketData.Returns.Count >= 250)
            {
                score += 0.2;
            }
            else if (marketData.Returns != null && marketData.Returns.Count >= 100)
            {
                score += 0.1;
            }

            // 账户健康度评分
            if (accountStatus.MarginLevel > 500)
            {
                score += 0.2;
            }
            else if (accountStatus.MarginLevel > 300)
            {
                score += 0.1;
            }

            // 近期表现评分
            if (accountStatus.ConsecutiveLosses == 0)
            {
                score += 0.1;
            }

            return Math.Min(1.0, score);
        }

        /// <summary>
        /// 获取安全模式参数
        /// </summary>
        private OptimizedParameters GetSafeModeParameters(MarketState marketState)
        {
            return new OptimizedParameters
            {
                PositionSize = MIN_POSITION_SIZE_NORMAL,
                Leverage = MIN_LEVERAGE_NORMAL,
                StopLoss = MIN_STOP_LOSS_RATIO * 2, // 更保守的止损
                GapRatio = MIN_GAP_RATIO,
                RetryCount = 3,
                TrendStrength = 0.0,
                CurrentVolatility = 0.02,
                PredictedVolatility = 0.025,
                MarketCondition = marketState,
                OptimizationTime = DateTime.Now,
                ConfidenceScore = 0.3
            };
        }

        #endregion

        #region 公共数据结构

        /// <summary>
        /// 市场数据
        /// </summary>
        public class MarketData
        {
            public string Symbol { get; set; }
            public List<double> Returns { get; set; }
            public List<double> Prices { get; set; }
            public double NetworkLatency { get; set; }
            public DateTime Timestamp { get; set; }
        }

        /// <summary>
        /// 账户状态
        /// </summary>
        public class AccountStatus
        {
            public double Equity { get; set; }
            public double FreeMargin { get; set; }
            public double MarginLevel { get; set; }
            public double MarginPerLot { get; set; }
            public int ConsecutiveLosses { get; set; }
            public DateTime LastTradeTime { get; set; }
        }

        #endregion
    }
}